Skip to content

fix: MCP-first Jira auth and diagnose Ambient env var accessibility#104

Merged
bobbravo2 merged 15 commits intoambient-code:mainfrom
angaduom:fix-jira-auth-detection
Apr 10, 2026
Merged

fix: MCP-first Jira auth and diagnose Ambient env var accessibility#104
bobbravo2 merged 15 commits intoambient-code:mainfrom
angaduom:fix-jira-auth-detection

Conversation

@vmrh21
Copy link
Copy Markdown
Contributor

@vmrh21 vmrh21 commented Apr 9, 2026

Summary

This PR contains multiple improvements to the CVE fixer workflow accumulated across test runs.

Jira Authentication Fixes (cve.find.md)

  • MCP-first detection: Use select:mcp__mcp-atlassian__jira_search directly instead of generic keyword ToolSearch (which returned wrong results). Read <available-deferred-tools> list directly — the tool name is visible there.
  • Credential flow: Bash env var diagnostic is now informational only — always attempt the curl API call regardless. Ambient secrets may be injected at the curl level even when invisible to shell checks.
  • base64 fix: Add | tr -d '\n' to prevent newline-wrapped auth headers on long credentials (aligned with fix(cve): use base64 -w 0 to prevent newline-broken auth headers #106).

New Command: /onboard (onboard.md)

Self-service onboarding command for new teams:

  • Guides interactively through Jira component name, repos, types, and container image names
  • Validates component name against Jira API (MCP-first)
  • Auto-discovers branch info from GitHub
  • Forks ambient-code/workflows if user lacks write access, syncs fork before branching
  • Opens PR automatically with mapping entry

Workflow Improvements (cve.fix.md)

  • Fork sync: gh repo sync before creating fix branches to ensure fork is up to date with upstream
  • All steps mandatory: Added mandatory execution rule — no step may be skipped or assumed complete without running
  • Step 4.5 CRITICAL: .cve-fix/ folder check explicitly marked mandatory with bash loop that always logs result
  • Step 10.5 binary scan: Post-fix verification now builds Go binary and scans it (govulncheck --mode binary) — gold standard vs source-only scan. Exit code checked before trusting output.
  • Automerge flag: --automerge flag enables gh pr merge --auto --squash after PR creation. Off by default. Guards against empty PR_URL.
  • Dependabot/Renovate detection: Existing PR check now runs 3 searches (CVE ID → bot author filter → broad package name) to avoid duplicating fixes already opened by bots
  • MCP-first Jira comments: VEX and fix-failed Jira comments note to use MCP tool if available

Documentation (README.md, ambient.json)

  • Added /onboard command section to README Available Commands
  • Updated Onboarding Steps to use /onboard instead of manual maintainer contact
  • Updated startupPrompt to mention /onboard as first step for new teams

CodeRabbit fixes

  • Search 3 (broad package): documented false-positive trade-off for common package names
  • Post-fix scan: scanner exit code checked — failure blocks PR creation rather than falsely passing
  • Python heredoc in onboard: variables passed as argv[] not interpolated into Python code (prevents injection)
  • onboard Jira validation: MCP-first + fixed shell injection in JQL encoding

Compatibility with #106

Both PRs touch cve.find.md and cve.fix.md but in non-overlapping sections. This PR pre-applies the base64 | tr -d '\n' fix from #106 to all auth lines for consistency, so whichever merges first the other will remain clean.

Test plan

  • Run /cve.find llm-d with Jira MCP configured — verify uses mcp__mcp-atlassian__jira_search without credential prompt
  • Run /cve.find AutoML in scheduled session — verify MCP tool is fetched via select: syntax
  • Run /onboard — verify interactive flow, auto-discovers branches, opens PR
  • Run /cve.fix --automerge — verify automerge enabled only on successful PR creation
  • Run /cve.fix on a Go repo — verify Step 10.5 builds binary and scans it

🤖 Generated with Claude Code

Two issues fixed:

1. MCP not checked proactively: workflow jumped straight to curl/env var
   auth and failed even when a Jira MCP server was available. Now Step 2
   explicitly checks for mcp__jira* / mcp__atlassian* tools first and uses
   MCP if found — no credentials needed from the user.

2. Ambient custom env vars not accessible to bash: env vars configured in
   Ambient session settings may not be automatically exported to bash
   subprocesses. Added a diagnostic step that checks accessibility before
   attempting the curl auth call, and gives a clear message with the
   specific export commands if the vars aren't reaching bash.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Jira access now prefers detected MCP Jira tools and skips curl/basic-auth when available; otherwise adds explicit token/export diagnostics and direct token-regeneration on HTTP 401. /cve.fix adds an opt-in --automerge flag, captures gh pr create output, requires a post-fix verification that can block PR creation and emit a fix-failed artifact, and tightens PR/open-PR detection. A new /onboard command doc was added to document interactive onboarding of Jira components and repo mappings.

Changes

Cohort / File(s) Summary
Jira access verification
workflows/cve-fixer/.claude/commands/cve.find.md
Detect session MCP Jira tools (mcp__jira*, mcp__atlassian*, etc.); if present, require MCP for Jira queries and skip curl/basic-auth setup. If absent, add explicit diagnostic to verify JIRA_API_TOKEN/JIRA_EMAIL are exported to the bash subprocess and instruct exporting if missing. Simplify curl credential handling: on HTTP 401 treat token invalid/expired and instruct generating/exporting a new token. Bifurcate Step 3: MCP path uses JQL via MCP (no auth), curl path uses constructed AUTH.
Automerge, PR flow & post-fix verification
workflows/cve-fixer/.claude/commands/cve.fix.md
Add --automerge flag parsed into AUTOMERGE=true/false, capture gh pr create output into PR_URL, and when enabled run gh pr merge --auto --squash "$PR_URL". Introduce mandatory “every step” execution/logging rule and per-repo guidance-file loop. Improve fork handling (tolerant fork create, gh repo sync, idempotent remote add/fetch). Rework open-PR detection to multi-stage search (CVE ID → package by bots → package fallback). Add post-fix verification: re-scan after changes (binary scan for Go when possible), block PR creation if CVE persists, write fix-failed report, and post Jira comment.
Onboarding command documentation
workflows/cve-fixer/.claude/commands/onboard.md
New /onboard interactive command doc: collects Jira component and repo details (optional container mappings), validates component via Jira (with credential fallback), auto-discovers repo release branches via gh, generates/edits JSON mapping entry, clones workspace (fork/sync when needed), injects mapping into component-repository-mappings.json, updates metadata, commits to onboard/<component-slug>, opens a PR with templated body, and cleans up temporary checkouts.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI as /cve.fix (CLI)
  participant Scanner
  participant Build as Build/Test Runner
  participant Verifier as Post-Fix Verifier
  participant GH as gh CLI
  participant GitHub

  User->>CLI: run /cve.fix [--automerge]
  CLI->>Scanner: run initial scan -> identify CVE
  CLI->>Build: run build/tests and apply fixes on branch
  Build->>Verifier: trigger post-fix scan
  Verifier-->>CLI: CVE resolved? (yes/no)
  alt CVE resolved
    CLI->>GH: gh pr create -> returns PR_URL
    GH->>GitHub: create PR
    alt AUTOMERGE=true
      CLI->>GH: gh pr merge --auto --squash PR_URL
      GH->>GitHub: merge PR
    end
  else CVE still present
    CLI->>GitHub: post Jira comment / write fix-failed artifact
  end
Loading
sequenceDiagram
  participant CLI as /cve.find (CLI)
  participant Env as Bash Env
  participant MCP as MCP Jira Tool
  participant JiraAPI as Jira REST

  CLI->>Env: inspect available session tools (mcp__jira*, mcp__atlassian*)
  alt MCP found
    CLI->>MCP: pass JQL to MCP tool (no auth setup)
    MCP->>JiraAPI: query Jira via MCP
  else MCP not found
    CLI->>Env: check JIRA_API_TOKEN and JIRA_EMAIL exported
    alt tokens present
      CLI->>JiraAPI: use curl with constructed AUTH
    else tokens missing
      CLI-->>Env: instruct export of JIRA_API_TOKEN/JIRA_EMAIL
    end
    JiraAPI-->>CLI: HTTP 401 => instruct generate/export new token
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main changes: MCP-first detection for Jira auth and environment variable accessibility diagnostics.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description accurately covers the changeset, detailing MCP-first Jira auth detection, the new /onboard command, workflow improvements including fork sync and binary scanning, and documentation updates with specific technical details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
workflows/cve-fixer/.claude/commands/cve.find.md (1)

115-203: ⚠️ Potential issue | 🔴 Critical

Critical: Missing MCP execution path in Step 3.

The documentation instructs Step 2.1 to detect MCP and "skip the curl/auth setup entirely," but Step 3 only provides curl-based code that references the ${AUTH} variable. This creates a critical logic gap:

  1. If MCP is detected in Step 2.1, AUTH is never defined
  2. Step 3's curl commands (lines 184-203, 238-253, 302-310) all reference ${AUTH}
  3. The workflow will fail with undefined variable errors

The comment at line 120 acknowledges "If using MCP... no AUTH needed," but there's no corresponding bash code showing how to execute the query using the MCP tool.

Required fix:

Step 3 needs conditional logic to handle both execution paths. For example:

🔧 Add MCP execution path to Step 3

At the beginning of Step 3, add a conditional check:

# Determine which path to use based on Step 2
if [[ $(list_available_tools) =~ mcp__jira|mcp__atlassian ]]; then
  USE_MCP=true
  echo "Using MCP tool for Jira query"
else
  USE_MCP=false
  echo "Using curl for Jira query"
fi

Then in section 3b (around line 184), replace the single curl execution with:

# Execute query based on authentication method
if [ "$USE_MCP" = "true" ]; then
  # MCP execution path
  # Call the appropriate MCP tool with JQL query
  # Example (adjust based on actual MCP tool interface):
  RESPONSE=$(mcp_jira_search --jql "${JQL}" --fields "key,summary,status,priority,created,components" --max-results 100)
  # Parse MCP response format (may differ from curl/JSON response)
  # Extract and save results appropriately
else
  # Curl execution path (existing code)
  RESPONSE=$(curl -s -w "\n%{http_code}" -X GET \
    --connect-timeout 10 \
    --max-time 30 \
    --retry 3 \
    --retry-delay 2 \
    -H "Content-Type: application/json" \
    -H "Authorization: Basic ${AUTH}" \
    "${JIRA_BASE_URL}/rest/api/3/search/jql?jql=${ENCODED_JQL}&fields=key,summary,status,priority,created,components&maxResults=100&startAt=0")
  # ... existing curl response handling ...
fi

Apply similar conditional logic to:

  • Pagination code (lines 238-253)
  • Comment fetching code (lines 302-310)

Alternative approach: If the specific MCP tool interface is not yet defined, add a clear TODO or placeholder in Step 3 indicating that MCP execution code needs to be added, and temporarily disable the MCP detection in Step 2 until the execution path is implemented.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.find.md` around lines 115 - 203, The
Step 3 code uses ${AUTH} and curl unconditionally causing failures when MCP was
detected in Step 2; add a conditional execution path controlled by a USE_MCP
flag (set from the existing MCP detection logic or via a small
list_available_tools check) and replace the direct curl calls that set
RESPONSE/HTTP_CODE/BODY with a branch: when USE_MCP=true invoke the MCP query
interface (e.g., mcp_jira_search or equivalent) using the JQL/ENCODED_JQL and
populate RESPONSE/HTTP_CODE/BODY in the same format expected by the rest of the
script (or add a clear TODO placeholder for MCP parsing if interface is
unknown), and when USE_MCP=false keep the existing curl+AUTH path; apply this
branching for the initial search, pagination loop, and comment-fetching sections
so AUTH is never referenced when MCP is used.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@workflows/cve-fixer/.claude/commands/cve.find.md`:
- Around line 76-90: Add blank lines before and after each code fence in the
markdown around the diagnostic bash snippet so static analysis stops flagging
formatting; specifically update the block containing TOKEN_SET and EMAIL_SET and
ensure there's an empty line before the opening ```bash and an empty line after
the closing ``` that precedes the bullet list and similarly an empty line before
the following ```bash export ...``` fence and after it so the code fences are
separated from surrounding text.

---

Outside diff comments:
In `@workflows/cve-fixer/.claude/commands/cve.find.md`:
- Around line 115-203: The Step 3 code uses ${AUTH} and curl unconditionally
causing failures when MCP was detected in Step 2; add a conditional execution
path controlled by a USE_MCP flag (set from the existing MCP detection logic or
via a small list_available_tools check) and replace the direct curl calls that
set RESPONSE/HTTP_CODE/BODY with a branch: when USE_MCP=true invoke the MCP
query interface (e.g., mcp_jira_search or equivalent) using the JQL/ENCODED_JQL
and populate RESPONSE/HTTP_CODE/BODY in the same format expected by the rest of
the script (or add a clear TODO placeholder for MCP parsing if interface is
unknown), and when USE_MCP=false keep the existing curl+AUTH path; apply this
branching for the initial search, pagination loop, and comment-fetching sections
so AUTH is never referenced when MCP is used.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a5f7e2ff-f09f-4b5f-9866-dd99de0f01fd

📥 Commits

Reviewing files that changed from the base of the PR and between 2239b41 and d238e1a.

📒 Files selected for processing (1)
  • workflows/cve-fixer/.claude/commands/cve.find.md

When passed, enables GitHub automerge on each PR after creation so it
merges automatically once all required checks pass. Off by default —
user must explicitly opt in.

Usage:
  /cve.fix --automerge
  /cve.fix RHOAIENG-4973 --automerge

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@workflows/cve-fixer/.claude/commands/cve.fix.md`:
- Around line 1236-1240: Update the fenced code block in the new usage example
so it satisfies markdownlint MD031/MD040: add a blank line before and after the
triple-backtick block and include a language identifier (e.g., text) after the
opening ```; specifically replace the snippet shown (the two lines with
"/cve.fix --automerge" and "/cve.fix RHOAIENG-4973 --automerge") with a fenced
block that begins with "```text", contains those two lines, and ends with "```",
ensuring there is an empty line above and below the fenced block.
- Around line 1082-1091: Add a guard that verifies PR_URL is non-empty before
attempting automerge: instead of only testing AUTOVERGE, update the conditional
around gh pr merge to require both AUTOMERGE="true" and a non-empty PR_URL
(e.g., test -n "$PR_URL"), and if PR_URL is empty emit an error message and
skip/exit rather than calling gh pr merge with an invalid URL; update the block
that references PR_URL, AUTOMERGE, and the gh pr merge command accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cd4e696d-19a5-4d1d-b0ee-bf6796593fa2

📥 Commits

Reviewing files that changed from the base of the PR and between d238e1a and 16eaf6c.

📒 Files selected for processing (1)
  • workflows/cve-fixer/.claude/commands/cve.fix.md

vmrh21 and others added 2 commits April 9, 2026 11:41
After applying the fix but before creating the PR, re-run the same scanner
(govulncheck/pip-audit/npm audit) to confirm the CVE is actually gone.

If CVE is still present after fix:
- Do NOT create a PR (fix was insufficient)
- Add Jira comment explaining the fix failed and why (transitive dep
  conflict, wrong package, etc.)
- Save to artifacts/cve-fixer/fixes/fix-failed-CVE-*.md

This catches cases like:
- Transitive dependency still pulling in the old vulnerable version
- Go toolchain directive not propagating correctly
- Wrong package targeted in the fix

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Previously only searched for PRs containing the CVE ID. Bots like
Dependabot and Renovate open PRs with just the package name and version
bump (e.g. "Bump urllib3 from 1.26.5 to 2.2.3") without mentioning the
CVE ID, causing the workflow to create duplicate fix PRs.

Now runs 3 searches before creating a PR:
1. CVE ID search — catches our own and manually created PRs
2. Package name + bot author filter — catches Dependabot/Renovate PRs
3. Package name broadly — catches any human PR for the same package

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
workflows/cve-fixer/.claude/commands/cve.fix.md (2)

1312-1315: ⚠️ Potential issue | 🟡 Minor

Fix fenced-block linting in the new --automerge usage example.

The block at Line 1312-Line 1315 is missing a language and blank-line spacing around the fence (MD031/MD040), matching a previously reported pattern.

Suggested fix
 Fix and enable automerge on all created PRs (merges automatically when checks pass):
-```
+
+```text
 /cve.fix --automerge
 /cve.fix RHOAIENG-4973 --automerge
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @workflows/cve-fixer/.claude/commands/cve.fix.md around lines 1312 - 1315,
The fenced code block showing usage for the /cve.fix command lacks a language
tag and surrounding blank lines, violating MD031/MD040; update the block (the
example containing "/cve.fix --automerge" and "/cve.fix RHOAIENG-4973
--automerge") to include a language identifier (e.g., ```text) and ensure there
is a blank line before and after the fenced block so the code fence is properly
spaced and lint-clean.


</details>

---

`1159-1163`: _⚠️ Potential issue_ | _🟠 Major_

**Guard automerge behind a non-empty PR URL before calling `gh pr merge`.**

At Line 1160-Line 1162, automerge runs only on `AUTOMERGE=true`, but not on successful PR creation. If `gh pr create` returns empty output, merge is attempted with invalid input. This was previously flagged and is still present.

<details>
<summary>Suggested guard</summary>

```diff
-# Enable automerge if --automerge flag was passed
-if [ "$AUTOMERGE" = "true" ]; then
+# Enable automerge if --automerge flag was passed
+if [ -z "$PR_URL" ]; then
+  echo "❌ PR creation did not return a URL; skipping automerge"
+elif [ "$AUTOMERGE" = "true" ]; then
   gh pr merge --auto --squash "$PR_URL"
   echo "✅ Automerge enabled on $PR_URL — will merge when checks pass"
 fi
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 1159 - 1163,
The automerge block uses AUTOMERGE and calls gh pr merge on PR_URL without
verifying PR_URL is non-empty; update the condition to require both
AUTOMERGE=true and a non-empty PR_URL (e.g., test -n "$PR_URL") before invoking
gh pr merge --auto --squash so you never call gh pr merge with an empty/invalid
PR URL; modify the guard around the gh pr merge call that references AUTOMERGE
and PR_URL accordingly.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @workflows/cve-fixer/.claude/commands/cve.fix.md:

  • Around line 1040-1058: Replace the hardcoded Basic auth flow around AUTH and
    the curl POST with the repository's MCP-first Jira auth pattern: detect and use
    the MCP-provided Jira token/credentials helper (instead of using JIRA_EMAIL and
    JIRA_API_TOKEN directly), fall back to well-documented env vars only if MCP is
    unavailable, and propagate diagnostics when env vars are missing; update the
    block that builds COMMENT_JSON and issues the curl POST to call the MCP auth
    helper (or export the MCP token into the Authorization header) and ensure
    variables referenced (COMMENT_TEXT, COMMENT_JSON, JIRA_BASE_URL, JIRA_KEY)
    remain unchanged so the POST uses the MCP-derived Authorization header rather
    than AUTH built from JIRA_EMAIL:JIRA_API_TOKEN.
  • Around line 1020-1032: The post-fix scan captures tool output into
    POST_SCAN_OUTPUT but never checks the scan command status, so a failed
    govulncheck (or pip-audit/npm audit) can produce an empty output and falsely
    mark CVE_STILL_PRESENT=false; update the block that runs govulncheck
    (GOTOOLCHAIN="go${TARGET_GO_VERSION}" govulncheck ...) to capture its exit code
    ($?) immediately and if non-zero either fail the workflow or set
    CVE_STILL_PRESENT=true and emit a clear error via echo/process logger; then only
    set CVE_STILL_PRESENT=false when the scan succeeded and grep of POST_SCAN_OUTPUT
    for $CVE_ID returns no match (apply the same exit-code check pattern for the
    Python/Node variants).
  • Around line 597-600: The EXISTING_PR lookup uses a loose gh pr list --search
    "$PACKAGE" which can match unrelated PRs for common package names; update the
    EXISTING_PR query (the gh pr list invocation that writes to EXISTING_PR) to
    tighten matching by requiring the package name appear as an exact word in the PR
    title or by additionally filtering for a security/CVE context (e.g., require
    "CVE" or "security" in the title/body) using the gh --jq filter so false
    positives are avoided; apply the same fix to the second occurrence of the gh pr
    list that appears around the 642–647 region so both searches use the stricter
    filter referencing $PACKAGE, TARGET_BRANCH and REPO_FULL.

Duplicate comments:
In @workflows/cve-fixer/.claude/commands/cve.fix.md:

  • Around line 1312-1315: The fenced code block showing usage for the /cve.fix
    command lacks a language tag and surrounding blank lines, violating MD031/MD040;
    update the block (the example containing "/cve.fix --automerge" and "/cve.fix
    RHOAIENG-4973 --automerge") to include a language identifier (e.g., ```text) and
    ensure there is a blank line before and after the fenced block so the code fence
    is properly spaced and lint-clean.
  • Around line 1159-1163: The automerge block uses AUTOMERGE and calls gh pr
    merge on PR_URL without verifying PR_URL is non-empty; update the condition to
    require both AUTOMERGE=true and a non-empty PR_URL (e.g., test -n "$PR_URL")
    before invoking gh pr merge --auto --squash so you never call gh pr merge with
    an empty/invalid PR URL; modify the guard around the gh pr merge call that
    references AUTOMERGE and PR_URL accordingly.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: ASSERTIVE

**Plan**: Pro

**Run ID**: `76288db4-5ead-4b19-8636-275995b368b2`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 16eaf6cad7b59159f4c44a6dd04ae3952afb0fdb and 9f94c2fa25cfa68b4229bab5e4a691df3efd5289.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `workflows/cve-fixer/.claude/commands/cve.fix.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment on lines +597 to +600
EXISTING_PR=$(gh pr list --repo "$REPO_FULL" --state open --base "$TARGET_BRANCH" \
--search "$PACKAGE" --json number,title,url --jq '.[0]' 2>/dev/null)
fi
fi
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Package-name fallback can skip unrelated PRs on common package terms.

At Line 597-Line 599, the third search picks the first open PR matching $PACKAGE on the target branch. For common names, this can create false positives and incorrectly skip required CVE fixes.

Proposed tightening
-EXISTING_PR=$(gh pr list --repo "$REPO_FULL" --state open --base "$TARGET_BRANCH" \
-  --search "$PACKAGE" --json number,title,url --jq '.[0]' 2>/dev/null)
+EXISTING_PR=$(gh pr list --repo "$REPO_FULL" --state open --base "$TARGET_BRANCH" \
+  --search "$PACKAGE" --json number,title,url \
+  --jq '[.[] | select(.title | test("(^|[^A-Za-z0-9])" + $pkg + "([^A-Za-z0-9]|$)"; "i"))
+              | select(.title | test("bump|upgrade|security|cve"; "i"))] | .[0]' \
+  --arg pkg "$PACKAGE" 2>/dev/null)

Also applies to: 642-647

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 597 - 600, The
EXISTING_PR lookup uses a loose gh pr list --search "$PACKAGE" which can match
unrelated PRs for common package names; update the EXISTING_PR query (the gh pr
list invocation that writes to EXISTING_PR) to tighten matching by requiring the
package name appear as an exact word in the PR title or by additionally
filtering for a security/CVE context (e.g., require "CVE" or "security" in the
title/body) using the gh --jq filter so false positives are avoided; apply the
same fix to the second occurrence of the gh pr list that appears around the
642–647 region so both searches use the stricter filter referencing $PACKAGE,
TARGET_BRANCH and REPO_FULL.

The post-fix verification was being skipped because it wasn't marked as
mandatory. Also, re-scanning source code (govulncheck ./...) after a fix
can give false negatives — the go.mod may be updated but the CVE could
still be present in the compiled binary if a transitive dep overrides it.

Changes:
- Mark Step 10.5 as CRITICAL/MANDATORY with explicit "Do NOT skip" warning
- For Go: build the binary first, then scan with govulncheck --mode binary
  (gold standard — verifies the actual compiled output, not just source)
- Fall back to source scan if binary build fails
- For Python: re-run pip-audit on modified requirements
- For Node: regenerate lockfile then npm audit

The workflow must not proceed to PR creation without completing this step.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (5)
workflows/cve-fixer/.claude/commands/cve.fix.md (5)

1033-1039: ⚠️ Potential issue | 🟠 Major

Post-fix scan still allows false pass on scanner failure.

POST_SCAN_OUTPUT is checked only via grep at Line 1060; scanner exit codes are not captured/validated. A failing govulncheck/pip-audit/npm audit can incorrectly produce CVE_STILL_PRESENT=false. This issue was previously raised and remains.

#!/bin/bash
# Verify whether post-fix scanners capture and validate exit status before grep checks.
rg -n -C3 'POST_SCAN_OUTPUT|POST_SCAN_EXIT|CVE_STILL_PRESENT|govulncheck|pip-audit|npm audit' workflows/cve-fixer/.claude/commands/cve.fix.md

Also applies to: 1060-1064

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 1033 - 1039,
The post-fix scanner output is stored in POST_SCAN_OUTPUT but its exit status
isn't checked, so failures from govulncheck/pip-audit/npm audit can produce
false "no CVE" results; capture each scanner's exit code (e.g.,
POST_SCAN_EXIT=$? right after running govulncheck/pip-audit/npm audit), and
update the logic that sets CVE_STILL_PRESENT to treat non-zero POST_SCAN_EXIT as
a scanner failure (set CVE_STILL_PRESENT=true or abort the job) before relying
on grep of POST_SCAN_OUTPUT; apply the same pattern for all scanner invocations
referenced by POST_SCAN_OUTPUT, POST_SCAN_EXIT, CVE_STILL_PRESENT, govulncheck,
pip-audit and npm audit so grep is only used for content checks when the scanner
exited successfully.

1345-1348: ⚠️ Potential issue | 🟡 Minor

Fix fenced-block markdownlint regression in usage example.

The usage snippet still needs fenced-block language and surrounding blank lines (MD031/MD040), matching the prior lint finding pattern.

Lint-compliant snippet
 Fix and enable automerge on all created PRs (merges automatically when checks pass):
-```
+```text
 /cve.fix --automerge
 /cve.fix RHOAIENG-4973 --automerge
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @workflows/cve-fixer/.claude/commands/cve.fix.md around lines 1345 - 1348,
The usage example for the /cve.fix command is missing a fenced code block
language and surrounding blank lines which triggers MD031/MD040; wrap the two
lines starting with "/cve.fix" in a fenced block annotated with a language
(e.g., ```text) and ensure there's a blank line before and after the fenced
block so the snippet for the /cve.fix usage becomes a proper fenced-block code
sample.


</details>

---

`1192-1195`: _⚠️ Potential issue_ | _🟠 Major_

**Guard automerge on non-empty `PR_URL` before merge.**

Automerge is gated only by `AUTOMERGE`; if `gh pr create` fails or returns empty output, `gh pr merge --auto --squash "$PR_URL"` can run with invalid input. This is a previously reported issue.  
 
<details>
<summary>Suggested guard</summary>

```diff
-      if [ "$AUTOMERGE" = "true" ]; then
+      if [ -z "$PR_URL" ]; then
+        echo "❌ PR creation did not return a URL; skipping automerge"
+      elif [ "$AUTOMERGE" = "true" ]; then
         gh pr merge --auto --squash "$PR_URL"
         echo "✅ Automerge enabled on $PR_URL — will merge when checks pass"
       fi
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 1192 - 1195,
Automerge currently runs purely on the AUTOMERGE flag and may call gh pr merge
with an empty PR_URL; update the guard so you only call gh pr merge --auto
--squash "$PR_URL" when PR_URL is non-empty (e.g., test [ -n "$PR_URL" ] or [[
-n "$PR_URL" ]]) and otherwise log an error and skip/exit; change the block
around the AUTOMERGE check that references $AUTOMERGE and $PR_URL so it verifies
PR_URL first and only runs gh pr merge when PR_URL contains a valid value.
```

</details>

---

`1084-1090`: _⚠️ Potential issue_ | _🟠 Major_

**Jira comment path still bypasses MCP-first auth flow.**

This block still hardcodes Basic auth from `JIRA_EMAIL:JIRA_API_TOKEN` and does not follow the MCP-first Jira strategy documented in `workflows/cve-fixer/.claude/commands/cve.find.md` (Context snippet 1). Same reliability gap as previously reported.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 1084 - 1090,
The code block currently builds a Basic auth header from
JIRA_EMAIL:JIRA_API_TOKEN (AUTH) and calls curl directly, which bypasses the
MCP-first Jira auth flow; replace the hardcoded Basic auth usage with the
MCP-first auth helper used elsewhere (e.g., call the project’s get_mcp_jira_auth
or equivalent helper to obtain the Authorization header) and pass that header to
the curl request that posts COMMENT_JSON to
"${JIRA_BASE_URL}/rest/api/3/issue/${JIRA_KEY}/comment"; keep a clear fallback
to the existing AUTH only if the MCP helper returns nothing, and ensure the
variable used in the curl -H "Authorization: ..." reflects the MCP token rather
than AUTH when available.
```

</details>

---

`597-599`: _⚠️ Potential issue_ | _🟠 Major_

**Tighten package-name fallback matching to avoid false-positive PR skips.**

Line 597 still uses a broad `--search "$PACKAGE"` fallback without contextual filtering, which can match unrelated open PRs for common package names and skip valid fixes. This is the same issue previously reported.  
 
<details>
<summary>Proposed tightening</summary>

```diff
-      EXISTING_PR=$(gh pr list --repo "$REPO_FULL" --state open --base "$TARGET_BRANCH" \
-        --search "$PACKAGE" --json number,title,url --jq '.[0]' 2>/dev/null)
+      EXISTING_PR=$(gh pr list --repo "$REPO_FULL" --state open --base "$TARGET_BRANCH" \
+        --search "$PACKAGE" --json number,title,url \
+        --jq '[.[] 
+              | select(.title | test("(^|[^A-Za-z0-9])" + $pkg + "([^A-Za-z0-9]|$)"; "i"))
+              | select(.title | test("bump|upgrade|security|cve"; "i"))] 
+              | .[0]' --arg pkg "$PACKAGE" 2>/dev/null)
```
</details>


Also applies to: 642-647

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 597 - 599,
EXISTING_PR discovery is too broad because it relies on --search "$PACKAGE"
which can match unrelated PRs; update the EXISTING_PR assignment (the gh pr list
call that sets EXISTING_PR) to remove the loose --search fallback and instead
call gh pr list with --json number,title,url (and baseRefName if available) and
use --jq filtering to select PRs whose title (and/or changed files) explicitly
matches the exact package name and the TARGET_BRANCH, ensuring you only pick PRs
that are truly for this package; apply the same tightening to the other gh pr
list usage around the block referenced (the second occurrence at lines ~642-647)
so both checks use the stricter jq-based matching rather than the broad --search
"$PACKAGE".
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @workflows/cve-fixer/.claude/commands/cve.fix.md:

  • Around line 1033-1039: The post-fix scanner output is stored in
    POST_SCAN_OUTPUT but its exit status isn't checked, so failures from
    govulncheck/pip-audit/npm audit can produce false "no CVE" results; capture each
    scanner's exit code (e.g., POST_SCAN_EXIT=$? right after running
    govulncheck/pip-audit/npm audit), and update the logic that sets
    CVE_STILL_PRESENT to treat non-zero POST_SCAN_EXIT as a scanner failure (set
    CVE_STILL_PRESENT=true or abort the job) before relying on grep of
    POST_SCAN_OUTPUT; apply the same pattern for all scanner invocations referenced
    by POST_SCAN_OUTPUT, POST_SCAN_EXIT, CVE_STILL_PRESENT, govulncheck, pip-audit
    and npm audit so grep is only used for content checks when the scanner exited
    successfully.
  • Around line 1345-1348: The usage example for the /cve.fix command is missing a
    fenced code block language and surrounding blank lines which triggers
    MD031/MD040; wrap the two lines starting with "/cve.fix" in a fenced block
    annotated with a language (e.g., ```text) and ensure there's a blank line before
    and after the fenced block so the snippet for the /cve.fix usage becomes a
    proper fenced-block code sample.
  • Around line 1192-1195: Automerge currently runs purely on the AUTOMERGE flag
    and may call gh pr merge with an empty PR_URL; update the guard so you only call
    gh pr merge --auto --squash "$PR_URL" when PR_URL is non-empty (e.g., test [ -n
    "$PR_URL" ] or [[ -n "$PR_URL" ]]) and otherwise log an error and skip/exit;
    change the block around the AUTOMERGE check that references $AUTOMERGE and
    $PR_URL so it verifies PR_URL first and only runs gh pr merge when PR_URL
    contains a valid value.
  • Around line 1084-1090: The code block currently builds a Basic auth header
    from JIRA_EMAIL:JIRA_API_TOKEN (AUTH) and calls curl directly, which bypasses
    the MCP-first Jira auth flow; replace the hardcoded Basic auth usage with the
    MCP-first auth helper used elsewhere (e.g., call the project’s get_mcp_jira_auth
    or equivalent helper to obtain the Authorization header) and pass that header to
    the curl request that posts COMMENT_JSON to
    "${JIRA_BASE_URL}/rest/api/3/issue/${JIRA_KEY}/comment"; keep a clear fallback
    to the existing AUTH only if the MCP helper returns nothing, and ensure the
    variable used in the curl -H "Authorization: ..." reflects the MCP token rather
    than AUTH when available.
  • Around line 597-599: EXISTING_PR discovery is too broad because it relies on
    --search "$PACKAGE" which can match unrelated PRs; update the EXISTING_PR
    assignment (the gh pr list call that sets EXISTING_PR) to remove the loose
    --search fallback and instead call gh pr list with --json number,title,url (and
    baseRefName if available) and use --jq filtering to select PRs whose title
    (and/or changed files) explicitly matches the exact package name and the
    TARGET_BRANCH, ensuring you only pick PRs that are truly for this package; apply
    the same tightening to the other gh pr list usage around the block referenced
    (the second occurrence at lines ~642-647) so both checks use the stricter
    jq-based matching rather than the broad --search "$PACKAGE".

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: ASSERTIVE

**Plan**: Pro

**Run ID**: `c22f67b7-9c7d-45a4-ab20-2392755d39f7`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 9f94c2fa25cfa68b4229bab5e4a691df3efd5289 and 5e46a412e3e79c0300ac275114397f9963b5b0f1.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `workflows/cve-fixer/.claude/commands/cve.fix.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

vmrh21 and others added 3 commits April 9, 2026 13:16
- Add mandatory execution rule at top: every step must be executed in
  order, none may be skipped. If a step produces no output, log it and
  continue — do not silently skip.
- Mark Step 4.5 (load .cve-fix/ guidance) as CRITICAL/MANDATORY with
  explicit bash loop that checks every cloned repo and always logs the
  result whether guidance is found or not.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
When a fork already exists from a previous run, its branches may be
weeks out of date. The fix branch would then be based on stale code,
potentially missing upstream changes or causing merge conflicts in the PR.

Now uses `gh repo sync --source upstream --branch TARGET_BRANCH` to
bring the fork's target branch up to date with upstream before creating
the fix branch. Logs a warning if sync fails but continues.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
New command guides teams through adding their component and repos to
component-repository-mappings.json and opens a PR automatically.

Features:
- Interactive: collects component name, repos, types, branches one step at a time
- Validates Jira component name against the API before proceeding
- Auto-discovers default branch and active release branches from GitHub
- Generates the correct JSON schema entry and shows it for confirmation
- Forks ambient-code/workflows if user lacks write access, syncs fork
  with upstream main before branching
- Creates PR with description including component details and next steps

Usage: /onboard (fully interactive)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (3)
workflows/cve-fixer/.claude/commands/cve.fix.md (3)

1229-1238: ⚠️ Potential issue | 🟠 Major

Validate PR_URL before attempting automerge.

At line 1235, automerge is attempted based only on the AUTOMERGE flag. If gh pr create at line 1229 fails (network issue, validation error, permission denied), PR_URL will be empty, and line 1236 will run gh pr merge --auto --squash "", producing a confusing error. Add a non-empty check for PR_URL before enabling automerge.

🐛 Proposed fix to validate PR_URL
       PR_URL=$(gh pr create \
         --base <target-branch> \
         --title "Security: Fix CVE-YYYY-XXXXX (<package-name>)" \
         --body "$PR_BODY")

       # Enable automerge if --automerge flag was passed
-      if [ "$AUTOMERGE" = "true" ]; then
+      if [ -z "$PR_URL" ]; then
+        echo "❌ PR creation did not return a URL; skipping automerge"
+      elif [ "$AUTOMERGE" = "true" ]; then
         gh pr merge --auto --squash "$PR_URL"
         echo "✅ Automerge enabled on $PR_URL — will merge when checks pass"
       fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 1229 - 1238,
Validate PR_URL after the `gh pr create` call (`PR_URL=$(gh pr create ...)`) and
before attempting automerge: ensure PR_URL is non-empty and likely valid; modify
the automerge block that currently checks only `if [ "$AUTOMERGE" = "true" ]` to
also check that `PR_URL` is not empty (e.g., `if [ "$AUTOMERGE" = "true" ] && [
-n "$PR_URL" ]`), and if PR_URL is empty, log an error or fail gracefully
instead of calling `gh pr merge --auto --squash ""`.

1386-1390: ⚠️ Potential issue | 🟡 Minor

Fix markdown formatting in usage example.

Lines 1387-1389 need blank lines before and after the code block, plus a language identifier to satisfy markdownlint MD031 and MD040. The past review flagged this and marked it as addressed, but the issue is still present in the current code.

📝 Proposed fix for markdown formatting
 Fix and enable automerge on all created PRs (merges automatically when checks pass):
-```
+
+```text
 /cve.fix --automerge
 /cve.fix RHOAIENG-4973 --automerge
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @workflows/cve-fixer/.claude/commands/cve.fix.md around lines 1386 - 1390,
The usage example code block containing "/cve.fix --automerge" and "/cve.fix
RHOAIENG-4973 --automerge" needs proper Markdown formatting: add a blank line
before and after the fenced code block and include a language identifier (e.g.,

fenced block around the existing lines so it becomes `\n\n```text\n/cve.fix
--automerge\n/cve.fix RHOAIENG-4973 --automerge\n```\n\n`.

1067-1097: ⚠️ Potential issue | 🔴 Critical

Post-fix scan missing exit code validation — can produce false negatives.

The scan commands at lines 1071, 1080, 1088, and 1096 don't capture or check exit codes. If govulncheck, pip-audit, or npm audit fails (tool missing, network timeout, build failure), the output will be empty or error text, and the grep -q "$CVE_ID" check at line 1102 will likely return false, incorrectly setting CVE_STILL_PRESENT=false. This allows a PR to be created even though the scan didn't actually verify the fix.

🐛 Proposed fix to capture and validate exit codes
+POST_SCAN_EXIT=0
+
 echo "Building and scanning binary to verify fix for CVE-${CVE_ID}..."
 cd "$REPO_DIR"

 # Build the binary with the fixed go.mod
 go build -o /tmp/fixed-binary-${REPO_NAME} ./... 2>&1

 if [ $? -eq 0 ]; then
   # Scan the compiled binary — this is the gold standard
   POST_SCAN_OUTPUT=$(GOTOOLCHAIN="go${TARGET_GO_VERSION}" \
     govulncheck -mode binary /tmp/fixed-binary-${REPO_NAME} 2>&1)
+  POST_SCAN_EXIT=$?
   rm -f /tmp/fixed-binary-${REPO_NAME}
 else
   echo "⚠️ Binary build failed — falling back to source scan"
   POST_SCAN_OUTPUT=$(GOTOOLCHAIN="go${TARGET_GO_VERSION}" govulncheck -show verbose ./... 2>&1)
+  POST_SCAN_EXIT=$?
 fi
 
 **For Python projects:**
 
 ```bash
 # Re-run pip-audit on the modified requirements file
 POST_SCAN_OUTPUT=$(pip-audit -r requirements.txt 2>&1)
+POST_SCAN_EXIT=$?

For Node.js projects:

# Re-run npm audit after package.json changes
npm install --package-lock-only 2>/dev/null  # regenerate lockfile
POST_SCAN_OUTPUT=$(npm audit --json 2>&1)
+POST_SCAN_EXIT=$?

Check result:

+if [ "${POST_SCAN_EXIT}" -ne 0 ]; then
+  echo "⚠️ Post-fix scan failed (exit ${POST_SCAN_EXIT}) — cannot verify fix. Skipping PR creation for safety."
+  CVE_STILL_PRESENT=true  # conservative: assume not fixed if we can't verify
+elif echo "$POST_SCAN_OUTPUT" | grep -q "$CVE_ID"; then
-if echo "$POST_SCAN_OUTPUT" | grep -q "$CVE_ID"; then
  CVE_STILL_PRESENT=true
else
  CVE_STILL_PRESENT=false
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workflows/cve-fixer/.claude/commands/cve.fix.md` around lines 1067 - 1097,
The post-fix scan steps (commands that set POST_SCAN_OUTPUT for govulncheck,
pip-audit, and npm audit) do not capture or validate exit codes, which can yield
false negatives; update each scan block that sets POST_SCAN_OUTPUT (the
govulncheck binary/source branches, the pip-audit block, and the npm audit
block) to also capture POST_SCAN_EXIT=$? immediately after the command, then
change the verification logic that sets CVE_STILL_PRESENT to first check
POST_SCAN_EXIT (treat non-zero as a failed/unverifiable scan and set
CVE_STILL_PRESENT=true and emit a warning), else fall back to the existing echo
"$POST_SCAN_OUTPUT" | grep -q "$CVE_ID" check to set CVE_STILL_PRESENT
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@workflows/cve-fixer/.claude/commands/cve.fix.md`:
- Around line 1115-1133: The Jira comment block currently builds Authorization
with AUTH from JIRA_EMAIL:JIRA_API_TOKEN and calls curl directly (see AUTH,
COMMENT_JSON and the curl POST); change this to follow the MCP-first pattern:
attempt to call any mcp__jira* helper/tool first to post the comment, and only
if that fails or is unavailable, construct AUTH from env vars; before using env
vars, detect if JIRA_EMAIL/JIRA_API_TOKEN are actually exported to the bash
subshell and, if not, emit the same diagnostic used in cve.find.md explaining
ambient-to-bash env visibility and fail with a clear message; ensure the final
curl POST still uses COMMENT_JSON but only after the MCP fallback check and the
env-var availability check.
- Around line 638-641: Add an inline comment next to the EXISTING_PR lookup (the
gh pr list invocation using --search "$PACKAGE" and the jq '.[0]' selection)
that documents the known false-positive trade-off: explain that Search 3
intentionally performs a broad search to catch human-opened PRs that may not
mention the CVE, that this can match generic package names (e.g., "client",
"utils", "config") and return unrelated PRs, and instruct operators to manually
review matches for such common PACKAGE values; state this limitation is accepted
to avoid creating duplicate PRs.

In `@workflows/cve-fixer/.claude/commands/onboard.md`:
- Around line 35-46: The snippet builds Basic auth with
JIRA_EMAIL:JIRA_API_TOKEN and calls curl (variables AUTH, JIRA_BASE_URL,
ENCODED, RESULT) without checking MCP tools; change it to follow the MCP-first
Jira auth pattern: first detect MCP tools named like mcp__jira* or
mcp__atlassian* and, if found, extract and use their credentials/URL for AUTH
and JIRA_BASE_URL; if no MCP tool is present, run the bash diagnostic used in
cve.find.md to confirm that JIRA_EMAIL/JIRA_API_TOKEN are exported to
subprocesses and only then build AUTH and call curl; ensure the logic falls back
to the original env-var Basic auth path when the diagnostic passes and emits a
clear error/exit when neither MCP tools nor usable env vars are available.
- Around line 156-171: The heredoc Python block currently injects shell
variables ${COMPONENT_NAME} and ${NEW_COMPONENT_JSON} directly into Python code
which can break parsing or allow injection; change the implementation to pass
the new component JSON via stdin (read with json.load(sys.stdin)) and pass
COMPONENT_NAME and MAPPING_FILE and the date as argv, or replace the whole step
with a jq command that safely updates data["components"] and
metadata.last_updated; update the Python heredoc to read from stdin and use
sys.argv (instead of interpolating ${NEW_COMPONENT_JSON} and ${COMPONENT_NAME})
so quoting/escaping issues are eliminated.

---

Duplicate comments:
In `@workflows/cve-fixer/.claude/commands/cve.fix.md`:
- Around line 1229-1238: Validate PR_URL after the `gh pr create` call
(`PR_URL=$(gh pr create ...)`) and before attempting automerge: ensure PR_URL is
non-empty and likely valid; modify the automerge block that currently checks
only `if [ "$AUTOMERGE" = "true" ]` to also check that `PR_URL` is not empty
(e.g., `if [ "$AUTOMERGE" = "true" ] && [ -n "$PR_URL" ]`), and if PR_URL is
empty, log an error or fail gracefully instead of calling `gh pr merge --auto
--squash ""`.
- Around line 1386-1390: The usage example code block containing "/cve.fix
--automerge" and "/cve.fix RHOAIENG-4973 --automerge" needs proper Markdown
formatting: add a blank line before and after the fenced code block and include
a language identifier (e.g., ```text) on the opening fence to satisfy
markdownlint MD031/MD040; update the fenced block around the existing lines so
it becomes `\n\n```text\n/cve.fix --automerge\n/cve.fix RHOAIENG-4973
--automerge\n```\n\n`.
- Around line 1067-1097: The post-fix scan steps (commands that set
POST_SCAN_OUTPUT for govulncheck, pip-audit, and npm audit) do not capture or
validate exit codes, which can yield false negatives; update each scan block
that sets POST_SCAN_OUTPUT (the govulncheck binary/source branches, the
pip-audit block, and the npm audit block) to also capture POST_SCAN_EXIT=$?
immediately after the command, then change the verification logic that sets
CVE_STILL_PRESENT to first check POST_SCAN_EXIT (treat non-zero as a
failed/unverifiable scan and set CVE_STILL_PRESENT=true and emit a warning),
else fall back to the existing echo "$POST_SCAN_OUTPUT" | grep -q "$CVE_ID"
check to set CVE_STILL_PRESENT accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6112e702-4a72-4859-a638-f61e83a142cf

📥 Commits

Reviewing files that changed from the base of the PR and between 5e46a41 and ca57c02.

📒 Files selected for processing (2)
  • workflows/cve-fixer/.claude/commands/cve.fix.md
  • workflows/cve-fixer/.claude/commands/onboard.md

vmrh21 and others added 3 commits April 10, 2026 07:44
Two fixes for the auth detection failure in automated runs:

1. MCP check: don't filter by specific tool name patterns (mcp__jira*).
   Jira MCP may appear under any name. Search ALL available tools and
   their descriptions. Also try mcp__session__refresh_credentials first
   to activate workspace-configured Jira credentials before checking.

2. Curl fallback: the bash env var diagnostic (TOKEN_SET=yes/no) was
   causing the workflow to stop when vars showed as "no". This is wrong
   — Ambient secrets can be injected at the curl level even when not
   visible to shell checks. Now the diagnostic is informational only
   and the API call is ALWAYS attempted. Only a 401 response (not a
   "no" from the bash check) stops the workflow.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Generic ToolSearch queries like "jira search issue JQL" match unrelated
tools instead of mcp__mcp-atlassian__jira_search. Now uses:
- select:mcp__mcp-atlassian__jira_search (exact)
- +atlassian jira (targeted)
Also tells the workflow to read the <available-deferred-tools> list
directly before searching, since the tool name is visible there.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…arch

Generic ToolSearch returns wrong results. The Jira tool name is visible
in <available-deferred-tools> at conversation start. Workflow now reads
that list directly and fetches with select:mcp__mcp-atlassian__jira_search
instead of relying on keyword search to discover it.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
vmrh21 and others added 4 commits April 10, 2026 15:19
…arch

After refresh_credentials activates Jira, the workflow was still doing
a generic ToolSearch ('jira search atlassian') which returns unrelated
results, causing a false 'tool not found' conclusion.

Now: Step A = refresh_credentials, Step B = immediately try
select:mcp__mcp-atlassian__jira_search with no generic search step.
Explicitly forbids generic keyword searches for tool discovery.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- README: add /onboard command section in Available Commands
- README: update Onboarding Steps to use /onboard instead of
  contacting maintainers manually
- ambient.json startupPrompt: mention /onboard as the first step
  for new teams before /cve.find and /cve.fix

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
cve.fix.md:
- Search 3 (broad package name): document false-positive trade-off so
  workflow uses judgment before skipping on common package names
- Post-fix scan: check exit code before grepping output — if scanner
  failed to run, treat as inconclusive and block PR creation
- Automerge: add non-empty PR_URL guard before calling gh pr merge
- Jira comment: add MCP-first note (use MCP tool if available)

onboard.md:
- Jira validation: use MCP-first pattern (select:mcp__mcp-atlassian__)
  with curl fallback; also fix shell injection in JQL encoding
- Python heredoc: pass all variables as argv[] instead of interpolating
  shell vars into Python code — prevents injection from component names
  containing quotes, backslashes, or newlines

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Prevents broken Authorization headers when credentials are long enough
to trigger base64 line-wrapping at 76 chars.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@bobbravo2 bobbravo2 merged commit d2ab1c9 into ambient-code:main Apr 10, 2026
2 checks passed
vmrh21 added a commit to angaduom/workflows that referenced this pull request Apr 10, 2026
Keep both the base64 | tr -d newline fix (from ambient-code#106) and the
diagnostic echo lines (from ambient-code#104) — they are complementary.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants